package p300;

import java.util.*;

/**
 *
 */
class Twitter {

    /**
     * 用户id，自己发布的推特列表
     */
    private Map<Integer, LinkedList<Integer>> oneself = new HashMap<>();
    /**
     * 用户id，用户自己发的和关注的人发的的推文列表
     */
    private Map<Integer, LinkedList<Integer>> all = new HashMap<>();
    /**
     * 用户id，关注的用户的用户id
     */
    private Map<Integer, HashSet<Integer>> follow = new HashMap<>();
    /**
     * 推特，推特发送时间
     */
    private Map<Integer, Integer> releaseTime = new HashMap<>();

    /**
     * 时间
     */
    private int time = 0;

    /**
     * Initialize your data structure here.
     */
    public Twitter() {
    }

    /**
     * Compose a new tweet.
     */
    public void postTweet(int userId, int tweetId) {
        // 更新用户自己发布的推特
        update(oneself, userId, tweetId);
        this.time++;
        if (!releaseTime.containsKey(tweetId)) {
            releaseTime.put(tweetId, time);
        }
        // 更新用户自己的总推特
        update(all, userId, tweetId);
        HashSet<Integer> set = follow.get(userId);
        if (set != null) {
            for (Integer id : set) {
                LinkedList<Integer> linkedList = all.get(id);
                if (linkedList != null) {
                    linkedList.addFirst(tweetId);
                } else {
                    linkedList = new LinkedList<>();
                    linkedList.addFirst(tweetId);
                    all.put(id, linkedList);
                }
            }
        }
    }

    private void update(Map<Integer, LinkedList<Integer>> map, int userId, int tweetId) {
        if (!map.containsKey(userId)) {
            LinkedList<Integer> linkedList = new LinkedList<>();
            linkedList.addFirst(tweetId);
            map.put(userId, linkedList);
        } else {
            LinkedList<Integer> linkedList = map.get(userId);
            linkedList.addFirst(tweetId);
        }
    }

    /**
     * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent.
     */
    public List<Integer> getNewsFeed(int userId) {
        LinkedList<Integer> list = new LinkedList<>();
        if (all.containsKey(userId)) {
            list = all.get(userId);
            //注意推特的长度最大为10
            if (list.size() > 10) {
                return list.subList(0, 10);
            }
        }
        return list;
    }

    /**
     * Follower follows a followee. If the operation is invalid, it should be a no-op.
     */
    public void follow(int followerId, int followeeId) {
//首先去掉自己关注自己的情况和已经关注过了的情况
        if (followeeId == followerId || (follow.get(followeeId) != null && follow.get(followeeId).contains(followerId))) {
            return;
        }
        //1、更新记录被关注者、关注者的map
        if (!follow.containsKey(followeeId)) {
            HashSet<Integer> set = new HashSet<>();
            set.add(followerId);
            follow.put(followeeId, set);
        } else {
            HashSet<Integer> set = follow.get(followeeId);
            set.add(followerId);
        }
        //2、更新关注者的总推特列表
        //①获取关注者的总推特列表
        LinkedList<Integer> linkedList = all.get(followerId);
        //②获取被关注者的个人推特列表
        LinkedList<Integer> linkedList1 = oneself.get(followeeId);
        //③更新列表
        //Ⅰ两个集合都不为空，将被关注者的推特全部加入到关注者的总推特列表中，按照推特发布时间排序
        if (linkedList != null && linkedList1 != null) {
            linkedList.addAll(linkedList1);
            timeSort(linkedList);
        } else {
            //Ⅱ如果关注者的总推特列表为空，而被关注者的列表不为空，更新：
            if (linkedList == null && linkedList1 != null) {
                linkedList = new LinkedList<>(linkedList1);
                all.put(followerId, linkedList);
            }
        }
    }

    private void timeSort(LinkedList<Integer> linkedList) {
        Comparator<Integer> comparator = (o1, o2) -> releaseTime.get(o2) - releaseTime.get(o1);
        linkedList.sort(comparator);
    }

    public void unfollow(int followerId, int followeeId) {
        //如果被取消关注者存在：
        if (follow.containsKey(followeeId)) {
            HashSet<Integer> set = follow.get(followeeId);
            //并且取消关注者存在于被取消关注者的集合中：
            if (set != null && set.contains(followerId)) {
                //将该关注者取消关注
                set.remove(followerId);
                //①获取被取消关注者的个人推特列表
                LinkedList<Integer> linkedList = oneself.get(followeeId);
                if (linkedList == null) {
                    return; //如果被取消关注者的个人推特列表为空，直接返回
                }
                //②获取当前取消关注者的总推特列表
                LinkedList<Integer> list = all.get(followerId);
                if (list == null) {
                    return;
                }
                //③走到这就意味着这两个表都不为空,那么在取消关注者的总推特列表中删除关注者的个人推特即可；
                for (int id : linkedList) {
                    list.remove(Integer.valueOf(id));
                }
            }
        }
    }

    public static void main(String[] args) {
    }
}
